<template>
  <Dialog
    ref="refDialog"
    title="选择印章"
    width="550"
    draggable
    @submit="onSelectSeal"
    @close="onClose"
    :hasFooter="style.isReady && state.list.length > 0"
  >
    <div ref="refBoxLoading" class="min-h-[146px]">
      <template v-if="style.isReady">
        <div class="grid box-seal" v-if="state.list.length > 0">
          <div
            @click="onSelect(item)"
            class="item-seal"
            :class="{ active: state.selectedInfo.sealSn == item.sealSn }"
            v-for="item in state.list"
          >
            <div can-click class="image-seal">
              <img :src="item.sealImageBase64" class="w-[90%]" alt="" />
              <IconChecked v-if="state.selectedInfo.sealSn == item.sealSn" />
            </div>
            <div class="text-center text-[#666] mt-1">{{ item.sealName }}</div>
          </div>
        </div>
        <template v-else>
          <NoData>暂无可用印章</NoData>
        </template>
      </template>
    </div>
  </Dialog>
</template>
<script setup>
import { reactive, toRefs, ref, onMounted, nextTick, inject } from "vue";
import IconChecked from "./_IconChecked.vue";
import { toast, format, seal, numbers, http } from "@/utils";
import $ from "jquery";
import _ from "lodash";
import { useResizeObserver, useDebounceFn } from "@vueuse/core";
import interact from "interactjs";

const refDialog = ref();
const refBoxLoading = ref();
const provideHome = inject("provideHome");
const { setBoxTemporarySeal } = provideHome.methods;

const state = reactive({
  style: {
    isReady: false,
    //是否终止加章流程
    isBreak: false,
    //加章流程是否处于进行中
    isSealAdding: true,
  },
  list: [],
  // list: [
  //   {
  //     sealType: "00",
  //     sealImageBase64: format.base64ToImageSrc(
  //       "iVBORw0KGgoAAAANSUhEUgAAAGQAAAAoCAYAAAAIeF9DAAAEtklEQVR42u1aeYhOURS/0jB20tgSIjEzZMmSNfsWIwYTk13CKCFJ5g/7niJrJEuKhD/QSDG2ZGRGYiI7ISH7bvic0/d7eX3NfO/d9+57777h1K9veeeee94995577rlHiP/0z9NGB20GECLAzlIwBmUIvXRQ5IUkf28YYUYIB70GYTThBOGLaUJ9Ixwk9NBByYgk70GPdFAlO4kwj3DHJJdxm7CIkOpE6MUYYSpQ5MIg8yUN55SqEN7Y7KsCYTZWuPGOTwnZhLq6L9X0OC8ZsTF7twe0csvje3PCjRgXs5XQIIyb1XfCOQcuKxHPEgPU/SY+J5aGyGktBrRsHJ7KhJxi/s/0yUXFo6WEER7Kb4dN3nNKxWBm2uBdTGgb8x9HIHdDFmxY0UTsL+Y99b0fcTR3dEqizdeY388J20JujP6Ee6aB5wmWgmdshA9+vAB38s7li7NxpmhijOoS/JMQQXK7h4S+xfDk+uWCr7rsyGj7g5CmgTF+EjrY4FsA3d9gLyiJ0sCX7LXiO9BRHRcyauMgxss4QwNj8EFupgXPMbx3N5uTbY/XSk9CRyqO+Afga1dqYIyGhCc2+FJs8OyK8Rq7vFC4OTqZr9hX39ckRI8olDMu5j/Ova1WrWyuBoPAp+aqIporaohJ0orQkdCT0DRAg6yykPFJxYAdkVC0M2G/+JsHsgvezL9gH3mNsPcBTsh5hNOEo4TdhA04t8xBNMb7zhBCP0JXGMkpdUI6xKkx11vwFKmYvelxnqebBjWfMBjnEBn5UzXLLNSDXiNt8lcEfzkbvJ+9UvoQlHCTUkjRIC0Sj5ZDv3grbprkOzz3QtGzhPEapiW8ooISZnYBzl8ydF3FgJnxHWHhBfhy9tsJCuTrTo1i9OSD41wHcq54qWQiNvGd2JSNlEE1m+0TTApy282aG2UCYRN0be1QxqsgFD8OpetZ8GUhNjeoD9ot09gorF8Nl+0DI54NWx1scEYVyVoNjaFiQI0jwTOEyYMITUT0Tshz+iz+Xn/KzhajqiRbE2OU92CGc8jcHkHSChHN6V0S0XzaS4xfkcq9lmPz8y6X7xjwdgjQGFz0sIYwWYSceiCeV+FPc4ppU1M4LKeRMEZSiEJ0x5tYWRchYMQUDEQ81j25tBkjqYRnnASc7kI2F5s9FtE8W1CTKnTGaBbnOV/Y1FbQxw+P9OcDb66wlxjlK+eThIE6GqKSsC75MUI/t8bgisHuimZwHYTpLKuQ8JHwVlIGZ5rPmAzF3wOtXORZ/9sHN8AHz3Wm32yUXw5ldYEu+/DbKF1SVX2+0mSgTX67qGk++OVZovgr1qFC/h6D71Hy8X0hdDrs4RjxfnpLyJdISVGexKpwa5BsCzcyTFIXPiNxydI14UM1SAzxIfMRxmGRCoHZENbYYXvZar1Cm2FykxBGRewmf0LvJbKN1wnrW0Qr4qSj3QqMBPTXz8EKXC/CR3wZdtO073D2nPOBowgtDaYGmNER5F3cEudsWtjgeyvc1b1mQOexIT9CsGvl29XhxkxbpbiDeJUXtbB8ixT2lxXiFeNbRNYfbmgABsq44NrrYb9t0Mdr4e6Ws9RRfRHN3HaEC6wcgA6XYZwtYRq4Pxvkd7gTiNdaAAAAAElFTkSuQmCC"
  //     ),
  //     width: "100.0",
  //     height: "40.0",
  //     sealBelongType: "01",
  //     sealUrl:
  //       "https://test.ebinterlink.com:8810/gxapp/common/readImage?imagePath=/data/newdzzbcg_upload/upload/20240705/abfa51e2e23e4c7ea35923234cfcffef/77310b94d50040b7915461ab81aca2c0.png",
  //     sealName: "手写签名",
  //     sealSn: "3d0c0962ea2748b2887d2d1312c9cc94",
  //   },
  //   {
  //     sealType: "04",
  //     sealImageBase64: format.base64ToImageSrc(
  //       "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"
  //     ),
  //     width: "90.0",
  //     height: "90.0",
  //     sealBelongType: "01",
  //     sealUrl:
  //       "https://test.ebinterlink.com:8810/gxapp/common/readImage?imagePath=/data/newdzzbcg_upload/upload/20240705/c4364a7de53141ddbb9243cc7b44756e/9348b8eb3b824c86ab4dec6db6823c98.png",
  //     sealName: "人名章",
  //     sealSn: "eedf8f8dc33b4ccd884e05d88a6858d9",
  //   },
  // ],
  selectedInfo: {},
});
const { style, formData } = toRefs(state);

const props = defineProps({
  /** gap骑缝章 */
  purpose: {
    type: String,
  },
});

const emits = defineEmits(["submit", "createHoverSeal"]);

const onSelect = item => {
  state.selectedInfo = item;
};

const onReset = () => {
  state.style.isReady = false;
  state.style.isSealAdding = false;
  state.list = [];
  state.selectedInfo = {};
  $(".box-confirm-seal").remove();
  setStatusSealAdd(EnumStatusAddSeal.none);
  $hoverSealBox = null;
  setBoxTemporarySeal(null);
};

let /** 悬浮印章容器*/
  $hoverSealBox,
  /** 悬浮印章图片 */
  $hoverSealImage,
  /** 悬浮印章显示宽度 */
  hoverSealShowWidth = 0,
  /** 悬浮印章显示高度 */
  hoverSealShowHeight = 0,
  /** 悬浮印章原始宽度 */
  hoverSealRawWidth = 0,
  /** 悬浮印章元素高度 */
  hoverSealRawHeight = 0,
  /** 添加印章所处状态 */
  statusSealAdd = "",
  /** 是否已绑过事件，用于控制只绑一次事件 */
  hasBindSealAddEvents = false;

const EnumStatusAddSeal = {
  /** hover 悬浮印章 */
  hover: "hover",
  /** confirm 确认印章 */
  confirm: "confirm",
  /** 不处于添加印章状态 */
  none: "",
};

let $viewerContainer = $("#viewerContainer");

const setSealSizeByScale = () => {
  if (
    [EnumStatusAddSeal.hover, EnumStatusAddSeal.confirm].includes(statusSealAdd)
  ) {
    var scaleFactor = seal.getScaleFactor();
    hoverSealShowWidth = hoverSealRawWidth * scaleFactor;
    hoverSealShowHeight = hoverSealRawHeight * scaleFactor;
    $hoverSealImage?.css({
      width: hoverSealShowWidth,
      height: hoverSealShowHeight,
    });
  }
};

const setStatusSealAdd = newStatus => {
  statusSealAdd = newStatus;
  if (newStatus != EnumStatusAddSeal.hover) {
    //不处于悬浮印章状态时，移除 .eventHoverSeal 命名空间的所有事件
    $viewerContainer.off(".eventHoverSeal");
  }
};

/** 移除悬浮印章 */
const clearHoverSeal = () => {
  $(".hover-seal").remove();
  $viewerContainer?.removeClass("status-hover-seal");
  setStatusSealAdd(EnumStatusAddSeal.none);
};

// 为provideHome 方法赋值，供其他组件使用
provideHome.methods.clearHoverSeal = clearHoverSeal;

/** 创建悬浮印章 */
const createHoverSeal = () => {
  clearHoverSeal();

  let elImage = document.createElement("img");
  let elBox = document.createElement("div");

  elImage.src = state.selectedInfo.sealImageBase64;
  elImage.className = "shower";

  let left = window.event.clientX;
  let top = window.event.clientY;

  elImage.onload = function () {
    setStatusSealAdd(EnumStatusAddSeal.hover);
    hoverSealRawWidth = state.selectedInfo.width;
    hoverSealRawHeight = state.selectedInfo.height;
    $hoverSealImage = $(elImage);
    setSealSizeByScale();

    $hoverSealBox = $(elBox).addClass("hover-seal initial");
    $hoverSealBox.append(elImage).appendTo("#viewer");

    // console.log({ hoverSealShowWidth, hoverSealShowHeight });
    $hoverSealBox.css({
      transform: `translate(${left - hoverSealShowWidth / 2}px , ${top - hoverSealShowHeight / 2}px)`,
    });

    // 添加 .status-hover-seal,可使 event.offsetX 相对于 .textLayer 的位置
    $viewerContainer.addClass("status-hover-seal");
    bindSealAddEvents();
    window.$hoverSealBox = $hoverSealBox;
  };
  emits("createHoverSeal");
  // elBox.appendChild(elImage);
};

const onClose = () => {
  if (!state.style.isSealAdding) {
    seal.exitAppLinkWhenSealAdd();
    provideHome.methods.setSealCurrentOperateName("");
  }
};

const bindSealAddEvents = () => {
  if (!hasBindSealAddEvents) {
    hasBindSealAddEvents = true;
    useResizeObserver(
      document.getElementById("viewer"),
      useDebounceFn(() => {
        if (
          provideHome.boxTemporarySeal ||
          statusSealAdd == EnumStatusAddSeal.hover
        ) {
          // console.log("resize ....");
          if (statusSealAdd == EnumStatusAddSeal.hover) {
            setSealSizeByScale();
          } else if (statusSealAdd == EnumStatusAddSeal.confirm) {
            setSealSizeByScale();
            let { style } = provideHome.boxTemporarySeal;
            style.setProperty("--sealWidth", hoverSealShowWidth + "px");
            style.setProperty("--sealHeight", hoverSealShowHeight + "px");
          }
        }
      }),
      100
    );
  }

  const getXYMax = $curPage => {
    return {
      xMax: $curPage.width() - hoverSealShowWidth,
      yMax: $curPage.height() - hoverSealShowHeight,
    };
  };

  $viewerContainer
    .on("scroll.eventHoverSeal", function (event) {
      let curScrollTop = $viewerContainer.scrollTop();
      //不知道为啥，通过 $hoverSealBox.data() 取得的数值跟 $hoverSealBox[0].dataset 不一样
      let { left, containerScrollTop, top } = $hoverSealBox[0].dataset;
      let finalLeft = left;
      let finalTop = +top + (curScrollTop - containerScrollTop);
      seal.move($hoverSealBox[0], {
        left: finalLeft,
        top: finalTop,
        containerScrollTop: curScrollTop,
      });
    })
    .on("mouseover.eventHoverSeal", ".canvasWrapper", function (event) {
      //通过data获取，旋转页面后，data的值没有变化，但是通过dataset获取的值变了
      let rotation = $(this).siblings(".textLayer")[0]?.dataset.mainRotation;
      $hoverSealBox[0].dataset.showerRotation = rotation;
      $hoverSealBox[0].classList.add("box-rotation");
    })
    .on("mousemove.eventHoverSeal", ".canvasWrapper", function (event) {
      /**
       * event.offset 鼠标相对于 .textLayer 的位置
       * event.client 相对于视口的位置
       * $("#viewer").offset() 相对于视口的位置
       */
      let rotation = $(this).siblings(".textLayer")[0]?.dataset.mainRotation;
      $hoverSealBox[0].dataset.showerRotation = rotation;
      $hoverSealBox[0].classList.add("box-rotation");

      // 容器相对于视口的数据
      let { top: containerOffsetTop, left: containerOffsetLeft } =
        $viewerContainer.offset();

      // 悬浮所在页相对于视口的数据
      let { top: pageOffsetTop, left: pageOffsetLeft } = $(this).offset();
      let scrollLeft = $viewerContainer.scrollLeft();

      let left =
        event.offsetX +
        scrollLeft +
        pageOffsetLeft -
        containerOffsetLeft -
        $hoverSealBox.width() / 2;
      let scrollTop = $viewerContainer.scrollTop();

      let top =
        event.offsetY +
        scrollTop +
        pageOffsetTop -
        containerOffsetTop -
        $hoverSealBox.height() / 2 +
        2.2; //偏移值，为什么是这个值，原因不清楚

      let finalLeft, finalTop;
      {
        //left、 top 边界值处理
        let minLeft = pageOffsetLeft - containerOffsetLeft + scrollLeft;
        let maxLeft = minLeft + $(this).width() - hoverSealShowWidth;
        finalLeft = format.valueInRange(minLeft, maxLeft, left);

        let minTop = pageOffsetTop - containerOffsetTop + scrollTop;
        let maxTop = minTop + $(this).height() - hoverSealShowHeight;
        finalTop = format.valueInRange(minTop, maxTop, top);
      }

      $hoverSealBox.removeClass("initial");
      seal.move($hoverSealBox[0], {
        left: finalLeft,
        top: finalTop,
        containerScrollTop: scrollTop,
      });
    })
    // .on("click.eventHoverSeal", ".textLayer", function (event) {
    //   // 坐标分析代码
    // })
    .on("click.eventHoverSeal", function (event) {
      // console.log("click", event);
      let $curPage = $(event.target).closest(".page");
      if ($curPage.length == 0) {
        //点击到无效区
        clearHoverSeal();
      } else {
        //点击到有效区
        // console.log("点击到有效区 ...", event);
        if (statusSealAdd != EnumStatusAddSeal.hover) {
          return;
        }
        if (EnumStatusAddSeal.hover) {
          var pageNumber = $curPage.data("pageNumber");
          let left = numbers.sub(event.offsetX - hoverSealShowWidth / 2);
          let top = numbers.sub(event.offsetY - hoverSealShowHeight / 2) + 2;

          let boxConfirmSeal = seal.createConfirmSeal({
            imgWidth: hoverSealShowWidth,
            imgHeight: hoverSealShowHeight,
            imgSrc: $hoverSealImage.attr("src"),
            rotation: $hoverSealBox[0].dataset.showerRotation,
          });

          boxConfirmSeal.dataset.pageNumber = pageNumber;

          let { xMax, yMax } = getXYMax($curPage);
          let xMin = 0,
            //最终left
            finalLeft = format.valueInRange(xMin, xMax, left);

          let yMin = 0,
            //最终top
            finalTop = format.valueInRange(yMin, yMax, top);

          $(boxConfirmSeal).appendTo($curPage);
          seal.move(boxConfirmSeal, {
            left: finalLeft,
            top: finalTop,
          });

          if (props.purpose == "continued") {
            //连续签章
            let position = seal.getRealPosition(boxConfirmSeal);
            $(boxConfirmSeal).addClass("seal-add-continued");
            emits("submit", {
              sealInfo: state.selectedInfo,
              posInfo: {
                ...position,
                page: $curPage.index() + 1,
              },
            });
            return;
          }

          //取消按钮点击事件
          $(".btn-cancel", boxConfirmSeal).on("click", function (event) {
            seal.exitAppLinkWhenSealAdd();
            event.stopPropagation();
            onReset();
            provideHome.methods.setSealCurrentOperateName("");
          });

          //确定按钮点击事件
          $(".btn-submit", boxConfirmSeal).on("click", function (event) {
            event.stopPropagation();
            let position = seal.getRealPosition(boxConfirmSeal);
            emits("submit", {
              sealInfo: state.selectedInfo,
              posInfo: {
                ...position,
                page: $curPage.index() + 1,
              },
            });
          });

          clearHoverSeal();
          setStatusSealAdd(EnumStatusAddSeal.confirm);

          //拖拽事件
          _.assign(provideHome.movePosition, {
            left: finalLeft,
            top: finalTop,
          });
          let position = provideHome.movePosition;
          interact(boxConfirmSeal).draggable({
            modifiers: [
              interact.modifiers.restrict({
                restriction: $curPage[0],
                elementRect: { left: 0, right: 0, top: 0, bottom: 1 },
              }),
            ],
            listeners: {
              start(event) {
                // console.log(event.type, event.target);
              },
              move(event) {
                // console.log("move ...");
                position.left += event.dx;
                position.top += event.dy;

                //用户可能缩放了viewer，move事件里的 xMax、yMax 需实时计算获得
                let { xMax, yMax } = getXYMax($curPage);

                position.left = format.valueInRange(xMin, xMax, position.left);
                position.top = format.valueInRange(yMin, yMax, position.top);

                // event.target.style.transform = `translate(${position.x}px, ${position.y}px)`;
                seal.move(event.target, {
                  left: position.left,
                  top: position.top,
                });
              },
            },
          });

          setBoxTemporarySeal(boxConfirmSeal);
        }
      }
    });
};

const onSelectSeal = () => {
  if (!state.selectedInfo.sealSn) {
    toast.warning("请先选择一个印章。");
    return;
  } else {
    state.style.isSealAdding = true;
    if (props.purpose == "gap") {
      emits("submit", {
        sealInfo: state.selectedInfo,
      });
    } else if (props.purpose == "byWord") {
      emits("submit", {
        sealInfo: state.selectedInfo,
      });
    } else {
      createHoverSeal();
    }
    refDialog.value.close();
  }
};

const initData = async () => {
  loading.show({
    target: refBoxLoading.value,
    background: "rgba(0,0,0,0)",
    text: "",
  });
  const [err, res] = await http.post({
    data: {
      serviceCode: "electronicSealSignature",
      featureCode: "getUserSeals",
    },
  });
  loading.close();
  if (res) {
    state.list = res.map(item => {
      return {
        ...item,
        sealImageBase64: format.base64ToImageSrc(item.sealImageBase64),
      };
    });
    if (state.list.length) {
      //默认选中第一项
      onSelect(state.list[0]);
    }
  }

  state.style.isReady = true;
};

onMounted(() => {});

defineExpose({
  show() {
    onReset();
    refDialog.value.show();
    nextTick(() => {
      //为了showLoading生效，用 nextTick 包一下
      initData();
    });
  },
  close() {
    clearHoverSeal();
    refDialog.value.close();
  },
});
</script>
<style lang="scss">
#viewerContainer {
  &.status-hover-seal,
  .status-confirm-seal {
    .textLayer {
      pointer-events: none;
      &:after {
        content: "";
        @apply absolute inset-0 bg-blue-500 opacity-10 z-50;
      }
    }
    [data-annotation-id] {
      @apply pointer-events-none;
    }
  }
}
.hover-seal {
  @apply absolute text-center pointer-events-none left-0 top-0;
  img {
    transition: all 0.3s ease-in-out;
    display: block;
  }
  &.initial {
    @apply fixed;
  }
}
</style>
<style lang="scss" scoped>
.box-seal {
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  .item-seal {
    &.active {
      .image-seal {
        border-color: #3461ff;
        background: linear-gradient(
            0deg,
            rgba(255, 255, 255, 0.9) 0%,
            rgba(255, 255, 255, 0.9) 100%
          ),
          #3461ff;
      }
    }
  }
  .image-seal {
    @apply relative hv-center;

    border: solid 0.6px var(--el-border-color);
    border-radius: 4px;
    padding: 10px 0;
    img {
      width: 100px;
      height: 100px;
      object-fit: contain;
    }
  }
}
</style>
